package com.kingsoft.labs.tangram.blocks.fs.drivers;

import java.util.ArrayList;
import java.util.Date;

import javax.jdo.PersistenceManager;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.annotations.Embedded;
import javax.jdo.annotations.EmbeddedOnly;

import com.google.appengine.api.datastore.*;

import com.kingsoft.labs.tangram.blocks.Block;
import com.kingsoft.labs.tangram.domain.Result;
import com.kingsoft.labs.tangram.domain.Task;

public class JDO extends Block {
	protected static PersistenceManager pm =
		PMF.get().getPersistenceManager();
	
	@Override
	public Result doTask(Task task) {
		
		return super.doTask(task);
	}
	
	protected Result doWrite(Task task) {
		return null;
	}

	public static final class PMF {
		private final static PersistenceManagerFactory pmfInstance =
			JDOHelper.getPersistenceManagerFactory("transactions-optional");
		
		public static PersistenceManagerFactory get() {
			return pmfInstance;
		}
	}
	
	@PersistenceCapable(identityType = IdentityType.APPLICATION)
	public static class SuperBlock {
		@PrimaryKey
		@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
		private Long id;
		@Persistent
		private String magic;
		@Persistent
		private String version;
		@Persistent
		private long blockSize;
		@Persistent
		private long freeBlockCount;
		@Persistent
		private ShortBlob bitmap;

		@Persistent
		@Embedded
		private OwnerInfo ownerInfo;

		@PersistenceCapable
		@EmbeddedOnly
		public static class OwnerInfo {
			@Persistent
			private String name;
			@Persistent
			private Date createDate;
			@Persistent
			private Date modifiedDate;
			@Persistent
			private boolean selfRead;
			@Persistent
			private boolean selfWrite;
			@Persistent
			private boolean otherRead;
			@Persistent
			private boolean otherWrite;
			public String getName() {
				return name;
			}
			public void setName(String name) {
				this.name = name;
			}
			public Date getCreateDate() {
				return createDate;
			}
			public void setCreateDate(Date createDate) {
				this.createDate = createDate;
			}
			public Date getModifiedDate() {
				return modifiedDate;
			}
			public void setModifiedDate(Date modifiedDate) {
				this.modifiedDate = modifiedDate;
			}
			public boolean isSelfRead() {
				return selfRead;
			}
			public void setSelfRead(boolean selfRead) {
				this.selfRead = selfRead;
			}
			public boolean isSelfWrite() {
				return selfWrite;
			}
			public void setSelfWrite(boolean selfWrite) {
				this.selfWrite = selfWrite;
			}
			public boolean isOtherRead() {
				return otherRead;
			}
			public void setOtherRead(boolean otherRead) {
				this.otherRead = otherRead;
			}
			public boolean isOtherWrite() {
				return otherWrite;
			}
			public void setOtherWrite(boolean otherWrite) {
				this.otherWrite = otherWrite;
			}
		}
		
		public OwnerInfo getOwnerInfo() {
			return ownerInfo;
		}
		public void setOwnerInfo(OwnerInfo ownerInfo) {
			this.ownerInfo = ownerInfo;
		}
		public Long getId() {
			return id;
		}
		public void setId(Long id) {
			this.id = id;
		}
		public String getMagic() {
			return magic;
		}
		public void setMagic(String magic) {
			this.magic = magic;
		}
		public String getVersion() {
			return version;
		}
		public void setVersion(String version) {
			this.version = version;
		}
		public long getBlockSize() {
			return blockSize;
		}
		public void setBlockSize(long blockSize) {
			this.blockSize = blockSize;
		}
		public long getFreeBlockCount() {
			return freeBlockCount;
		}
		public void setFreeBlockCount(long freeBlockCount) {
			this.freeBlockCount = freeBlockCount;
		}
		public ShortBlob getBitmap() {
			return bitmap;
		}
		public void setBitmap(ShortBlob bitmap) {
			this.bitmap = bitmap;
		}
	}
	
	@PersistenceCapable(identityType = IdentityType.APPLICATION)
	public static class INode {
		@PrimaryKey
		@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
		private Long id;
		@Persistent
		private INode parent;
		@Persistent
		private String type;
		@Persistent
		private Long sizeLong;
		@Persistent
		private String name;
		@Persistent
		private ArrayList<DataBlock> blocks;
		public ArrayList<DataBlock> getBlocks() {
			return blocks;
		}
		public void setBlocks(ArrayList<DataBlock> blocks) {
			this.blocks = blocks;
		}
		public Long getId() {
			return id;
		}
		public void setId(Long id) {
			this.id = id;
		}
		public INode getParent() {
			return parent;
		}
		public void setParent(INode parent) {
			this.parent = parent;
		}
		public String getType() {
			return type;
		}
		public void setType(String type) {
			this.type = type;
		}
		public Long getSizeLong() {
			return sizeLong;
		}
		public void setSizeLong(Long sizeLong) {
			this.sizeLong = sizeLong;
		}
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
	}
	
	@PersistenceCapable(identityType = IdentityType.APPLICATION)
	public static class DataBlock {
		@PrimaryKey
		@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
		private Long id;
		@Persistent
		private Blob data;
		public Long getId() {
			return id;
		}
		public void setId(Long id) {
			this.id = id;
		}
		public Blob getData() {
			return data;
		}
		public void setData(Blob data) {
			this.data = data;
		}
	}
}
